

"""
中介模式：用一个中介对象来封装一系列的对象的交互，中介者使各对象不需要显示地相互引用，从而使耦合松散，而且可以独立地改变他们之间的交互
比如：房客与房东之间的交互过程是由中介来承担的，房客不需要知道房东是谁，房东也不需要知道房客是谁，有什么问题，直接找找中介就可以了。
中介模式的三个对象：交互对象、中介者、具体中介者
"""
class InteractiveObject:
    """进行交互的对象"""
    pass


class InteractiveObjectImplA:
    """实现类A"""
    pass


class InteractiveObjectImplB:
    """实现类B"""
    pass


class Meditor:
    """中介类"""
    def __init__(self):
        self.__interactiveObjA = InteractiveObjectImplA()
        self.__interactiveObjB = InteractiveObjectImplB()

    def interactive(self):
        """进行交互的操作"""
        # 通过self.__interactiveObjA和self.__interactiveObjB完成相应的交互操作
        pass


# 客户端不可能分别与每个通信设备进行直接交互，可以在两者之间创建一个设备管理器
from abc import ABCMeta, abstractmethod
from enum import Enum


class DeviceType(Enum):
    """设备类型"""
    TypeSpeaker = 1
    TypeMicrophone = 2
    TypeCamera = 3


class DeviceItem:
    """设备项"""
    def __init__(self, id, name, type, isDefault=False):
        self.__id = id
        self.__name = name
        self.__type = type
        self.__isDefault = isDefault

    def __str__(self):
        return "type:" + str(self.__type) + " id:" + str(self.__id) + " name:" + str(self.__name) + " isDefault:" + str(self.__isDefault)
    
    def getId(self):
        return self.__id

    def getName(self):
        return self.__name
    
    def getType(self):
        return self.__type

    def isDefault(self):
        return self.__isDefault


class DeviceList:
    """设备列表"""
    def __init__(self):
        self.__devices = []

    def add(self, deviceItem):
        self.__devices.append(deviceItem)

    def getCount(self):
        return len(self.__devices)

    def getByIdx(self, idx):
        if idx < 0 or idx >= self.getCount():
            return None
        return self.__devices[idx]

    def getById(self, id):
        for item in self.__devices:
            if(item.getId() == id):
                return item
        return None

class DeviceMgr(metaclass=ABCMeta):
    @abstractmethod
    def enumerate(self):
        """
        枚举设备列表
        （在程序初始化时，有设备插拔时都要重新获取设备列表
        """
        pass

    @abstractmethod
    def active(self, deviceId):
        """选择要是用的设备"""
        pass

    @abstractmethod
    def getCurDeviceId(self):
        """获取当前正在使用的设备ID"""
        pass

class SpeakerMgr(DeviceMgr):
    """扬声器设备管理类"""
    def __init__(self):
        self.__curDeviceId = None

    def enumerate(self):
        devices = DeviceList()
        devices.add(DeviceItem("32ffqwq232-232dsdw3-23dws32-332dwd", "Realtek High Definition Audio", DeviceType.TypeSpeaker))

        devices.add(DeviceItem("d22d32333-ddsd23d3-dws3d2-d32dd2", "NVIDIA High Definition Audio", DeviceType.TypeSpeaker, True))
        return devices

    def active(self, deviceId):
        self.__curDeviceId = deviceId

    def getCurDeviceId(self):
        return self.__curDeviceId


class DeviceUtil:
    """设备工具类"""
    def __init__(self):
        self.__mgrs = {}
        self.__mgrs[DeviceType.TypeSpeaker] = SpeakerMgr()
        # MicrophoneMgr和CameraMgr不再实现
        # self.__mgrs[DeviceType.TypeMicrophone] = MicrophoneMgr()
        # self.__mgrs[DeviceType.TypeCamera] = CameraMgr()

    def __getDeviceMgr(self, type):
        return self.__mgrs[type]

    def getDeviceList(self, type):
        return self.__getDeviceMgr(type).enumerate()

    def active(self, type, deviceId):
        self.__getDeviceMgr(type).active(deviceId)

    def getCurDeviceId(self, type):
        return self.__getDeviceMgr(type).getCurDeviceId()

if __name__ == "__main__":
    deviceUtil = DeviceUtil()
    deviceList = deviceUtil.getDeviceList(DeviceType.TypeSpeaker)
    print("麦克风设备：")
    if deviceList.getCount() > 0:
        deviceUtil.active(DeviceType.TypeSpeaker, deviceList.getByIdx(0).getId())
    for idx in range(0, deviceList.getCount()):
        device = deviceList.getByIdx(idx)
        print(device)
    print("当前使用的设备：" + deviceList.getById(deviceUtil.getCurDeviceId(DeviceType.TypeSpeaker)).getName())


